﻿/*
This project and all of its code is/are Copyright (C) 2017  Nils Hunter Alving

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using DynamicDependencyContainer.Models;
using InterfaceTestData.Interfaces.PropertiesOnly;
using InterfaceTestData.ImplementationClasses.PropertiesOnly;

namespace DynamicDependencyContainerUnitTests
{
    [TestClass]
    public class RegisteredTypeTests
    {
        [ExpectedException(typeof(ArgumentException))]
        [TestMethod]
        public void ConstructorWithTwoTypeParams_UseInterfaceForBothParams_ThrowsException()
        {
            var regType = new RegisteredType<IClaim>(typeof(IClaim),typeof(IClaim), null);
        }
        [ExpectedException(typeof(ArgumentException))]
        [TestMethod]
        public void ConstructorWithTwoTypeParams_ClassWithNoDefaultConstructor_ThrowsException()
        {
            var regType = new RegisteredType<IClaim>(typeof(IClaim), typeof(Claim), null);
        }
        [ExpectedException(typeof(ArgumentException))]
        [TestMethod]
        public void ConstructorWithConstrctArguments_MissingConstArgs_ThrowsException()
        {
            var regType = new RegisteredType<IClaim>(typeof(IClaim), typeof(Claim), new object[] { DateTime.Now}, null);
        }
        [ExpectedException(typeof(ArgumentException))]
        [TestMethod]
        public void ConstructorWithConstrctArguments_TooManyConstrctArgs_ThrowsException()
        {
            var regType = new RegisteredType<IClaim>(typeof(IClaim), typeof(Claim), new object[] { DateTime.Now, "asdf", "qwer" }, null);
        }
        [ExpectedException(typeof(ArgumentException))]
        [TestMethod]
        public void ConstructorWithConstrctArguments_ArgsOutOfOrder_ThrowsException()
        {
            var regType = new RegisteredType<IClaim>(typeof(IClaim), typeof(Claim), new object[] { "MM/dd/yyyy", DateTime.Now }, null);
        }
        [TestMethod]
        public void Resolve_ClassWithDefaultConstructor_ReturnsValidObject()
        {
            var regType = new RegisteredType<IClaimRep>(typeof(IClaimRep), typeof(ClaimRep), null);
            var claimRep = regType.Resolve() as ClaimRep;
            Assert.IsNotNull(claimRep);
            Assert.IsTrue(regType.CanResolveType(typeof(IClaimRep)));
        }
        [TestMethod]
        public void Resolve_ConstructorWithTwoTypeParams_ClassWithDefaultConstructor_ReturnsValidObject()
        {
            var regType = new RegisteredType<IClaimRep>(typeof(IClaimRep), typeof(ClaimRep), null);
            var claimRep = regType.Resolve() as ClaimRep;
            Assert.IsNotNull(claimRep);
        }
        [TestMethod]
        public void Resolve_ConstructorWithInstanceParam_ReturnsTheOriginalInstanceTwiceObject()
        {
            var firstName = "John";
            var lastName = "Yaya";
            var claimRep = new ClaimRep() { FirstName = firstName, LastName = lastName };
            var regType = new RegisteredType<IClaimRep>(typeof(IClaimRep), claimRep, null);
            var resolvedClaimRep = regType.Resolve() as ClaimRep;
            Assert.IsNotNull(resolvedClaimRep);
            Assert.IsTrue(regType.CanResolveType(typeof(IClaimRep)));
            Assert.AreEqual(firstName,resolvedClaimRep.FirstName);
            Assert.AreEqual(lastName, resolvedClaimRep.LastName);
        }
        [TestMethod]
        public void Resolve_ConstructorWithConstrctArguments_ClassWithNoDefaultConstructor_ReturnsValidObject()
        {
            var formatString = "MM/dd/yyy";
            var now = DateTime.Now;
            var nowString = now.ToString(formatString);
            var regType = new RegisteredType<IClaim>(typeof(IClaim), typeof(Claim), new object[] { now, "MM/dd/yyyy" }, null);
            var claim = regType.Resolve() as Claim;
            Assert.IsNotNull(claim);
            Assert.IsTrue(regType.CanResolveType(typeof(IClaim)));
            Assert.AreEqual(now, claim.LossDateTime);
            Assert.AreEqual(nowString, claim.FormattedLossDate);
        }
        [TestMethod]
        public void New_ClassWithDefaultConstructor_ReturnsValidObject()
        {
            var regType = new RegisteredType<IClaimRep>(typeof(IClaimRep), typeof(ClaimRep), null);
            var claimRep = regType.Resolve() as ClaimRep;
            Assert.IsNotNull(claimRep);
            Assert.IsTrue(regType.CanResolveType(typeof(IClaimRep)));
        }
    }
}
